<script setup lang="ts" name="CkItem">
import { toRefs } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { useDrag, useDrop } from 'vue3-dnd'
import { getEmptyImage } from 'react-dnd-html5-backend'
import { useLayoutStore } from '@/store/bigScreen/layoutStore'
import { cloneDeep } from 'lodash-es'
import { getParent, getNearDropIndex, getNearIndex, findFirstVisible, findLastVisible, findVisibleLength } from '../../../utils'

const layoutStore = useLayoutStore()

const { isLayoutDragging, isNear, isNearSelf, dropTo, dropLevel, dropIndex, dropId, isItemSort, layout, currentDragging, currentDragModule } = storeToRefs(layoutStore)

const props = defineProps({
  info: {
    type: Object,
    default: () => {
      return {}
    }
  },
  preview: {
    type: Boolean,
    default: false
  },
  index: {
    type: Number,
    default: 0
  }
})

const cardRef = ref(null)

const [, drop] = useDrop({
  accept: props.info.config.acceptDragType,
  canDrop: () => {
    return isItemSort.value
  },
  hover: (item: any, monitor) => {
    if (!cardRef.value) return
    const hoverBoundingRect = cardRef.value?.getBoundingClientRect()
    const clientOffset = monitor.getClientOffset()
    if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5) {
      if (isItemSort.value) {
        if (item.config.position === 'bottom') {
          const dragTabIndex = layout.value.bottom.findIndex((v) => v.id === item.parent[item.parent.length - 1])
          const nearItemBeforeIndex = item.pid === props.info.pid ? getNearIndex(layout.value.bottom[dragTabIndex].children, item.index, 'before') : -1
          const nearItemAfterIndex = item.pid === props.info.pid ? getNearIndex(layout.value.bottom[dragTabIndex].children, item.index, 'after') : -1
          if (item.id !== props.info.id && item.pid === props.info.pid && clientOffset.x - hoverBoundingRect.left < 15 && clientOffset.x - hoverBoundingRect.left > 0 && props.index !== nearItemBeforeIndex && nearItemBeforeIndex !== -1) {
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = item.config.position
            dropIndex.value = getNearDropIndex(nearItemBeforeIndex, props.index, 'before')
            dropId.value = props.info.pid
            dropLevel.value = 'item'
            layoutStore.moveLayout(item)
          } else if (item.id !== props.info.id && item.pid === props.info.pid && hoverBoundingRect.right - clientOffset.x < 15 && hoverBoundingRect.right - clientOffset.x > 0 && props.index !== nearItemAfterIndex && nearItemAfterIndex !== -1) {
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = item.config.position
            dropIndex.value = getNearDropIndex(nearItemAfterIndex, props.index, 'after')
            dropId.value = props.info.pid
            dropLevel.value = 'item'
            layoutStore.moveLayout(item)
          } else {
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = item.config.position
            dropIndex.value = item.index
            dropId.value = props.info.pid
            dropLevel.value = 'item'
            layoutStore.moveLayout(item)
          }
        } else {
          const dragAsideIndex = item.config.position === 'root' ? layout.value.root.findIndex((v) => v.id === item.parent[item.parent.length - 1]) : 0
          const dragColumnIndex = layout.value[item.config.position][dragAsideIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
          const dragTabIndex = layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 3])
          const nearItemBeforeIndex = item.pid === props.info.pid ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children, item.index, 'before') : -1
          const nearItemAfterIndex = item.pid === props.info.pid ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children, item.index, 'after') : -1
          if (item.id !== props.info.id && item.pid === props.info.pid && clientOffset.x - hoverBoundingRect.left < 15 && clientOffset.x - hoverBoundingRect.left > 0 && props.index !== nearItemBeforeIndex && nearItemBeforeIndex !== -1) {
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = item.config.position
            dropIndex.value = getNearDropIndex(nearItemBeforeIndex, props.index, 'before')
            dropId.value = props.info.pid
            dropLevel.value = 'item'
            layoutStore.moveLayout(item)
          } else if (item.id !== props.info.id && item.pid === props.info.pid && hoverBoundingRect.right - clientOffset.x < 15 && hoverBoundingRect.right - clientOffset.x > 0 && props.index !== nearItemAfterIndex && nearItemAfterIndex !== -1) {
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = item.config.position
            dropIndex.value = getNearDropIndex(nearItemAfterIndex, props.index, 'after')
            dropId.value = props.info.pid
            dropLevel.value = 'item'
            layoutStore.moveLayout(item)
          } else {
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = item.config.position
            dropIndex.value = item.index
            dropId.value = props.info.pid
            dropLevel.value = 'item'
            layoutStore.moveLayout(item)
          }
        }
      } else {
        return
      }
    } else {
      if (isItemSort.value) {
        isItemSort.value = false
        layoutStore.setCurrentDraggingPreviewModule(item)
      }
      return
    }
  },
  drop() {
    if (isItemSort.value) {
      isItemSort.value = false
      currentDragging.value = null
      isLayoutDragging.value = false
      currentDragModule.value = null
      dropLevel.value = ''
    }
  }
})

const [dragCollect, drag, preview] = useDrag({
  type: props.info.config.dragType,
  item: () => {
    const res = cloneDeep(props.info)
    res.component = null
    res.index = props.index
    if (res.config.position === 'left') {
      res.parent = getParent(layout.value.left, res.id)
      const index = layout.value.left[0].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
      if (index === findLastVisible(layout.value.left[0].children) && findVisibleLength(layout.value.left[0].children[index].children) === 1 && findVisibleLength(layout.value.left[0].children[index].children[0].children) === 1) {
        res.isNearMain = true
      } else {
        res.isNearMain = false
      }
    } else if (res.config.position === 'right') {
      res.parent = getParent(layout.value.right, res.id)
      const index = layout.value.right[0].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
      if (index === findFirstVisible(layout.value.right[0].children) && findVisibleLength(layout.value.right[0].children[index].children) === 1 && findVisibleLength(layout.value.right[0].children[index].children[0].children) === 1) {
        res.isNearMain = true
      } else {
        res.isNearMain = false
      }
    } else if (res.config.position === 'bottom') {
      res.parent = getParent(layout.value.bottom, res.id)
      console.log(res.parent, 'bottom')
      const index = layout.value.bottom.findIndex((v) => v.id === res.pid)
      if (index === findFirstVisible(layout.value.bottom) && findVisibleLength(layout.value.bottom[index].children) === 1) {
        res.isNearMain = true
      } else {
        res.isNearMain = false
      }
    } else {
      res.parent = getParent(layout.value.root, res.id)
      res.isNearMain = false
    }
    if (res.config.position === 'bottom') {
      const dragTabIndex = layout.value.bottom.findIndex((v) => v.id === res.parent[res.parent.length - 1])
      if (findVisibleLength(layout.value.bottom[dragTabIndex].children) > 1) {
        isItemSort.value = true
      } else {
        isItemSort.value = false
      }
      console.log(isItemSort.value, 'bottom')
    } else {
      const dragAsideIndex = res.config.position === 'root' ? layout.value.root.findIndex((v) => v.id === res.parent[res.parent.length - 1]) : 0
      const dragColumnIndex = layout.value[res.config.position][dragAsideIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
      const dragTabIndex = layout.value[res.config.position][dragAsideIndex].children[dragColumnIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 3])
      if (findVisibleLength(layout.value[res.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children) > 1) {
        isItemSort.value = true
      } else {
        isItemSort.value = false
      }
    }
    layoutStore.setCurrentDraggingPreviewModule(res)
    return res
  },
  canDrag: () => {
    return props.info.config.canDrag
  },
  collect: (monitor) => ({
    isDragging: monitor.isDragging()
  })
})

const { isDragging } = toRefs(dragCollect)

const setRef = (el) => {
  cardRef.value = drag(drop(el))
}

watch(
  () => isDragging.value,
  (value) => {
    isLayoutDragging.value = value
  }
)

const changeTab = (item) => {
  layoutStore.changeTab(item)
}

const setClass = computed(() => {
  return {
    active: isNearSelf.value,
    'is-active': props.info.active,
    'is-check': currentDragModule.value && currentDragModule.value.id === props.info.id && !isItemSort.value && isNearSelf.value && !props.preview,
    preview: props.preview,
    default: !props.preview,
    'left': props.info.config.position === 'left',
    'right': props.info.config.position === 'right',
    'root': props.info.config.position === 'root'
  }
})

const opacity: any = computed(() => {
  return currentDragging.value && currentDragging.value.id === props.info.id ? 0 : 1
})

onMounted(() => {
  preview(getEmptyImage(), { captureDraggingState: true })
})
</script>

<template>
  <div :ref="setRef" class="el-tabs__item is-top" @click="changeTab(props.info)" :class="setClass" :style="{ opacity }">
    <div class="tab-item-label">{{ props.info.title }}</div>
  </div>
</template>

<style scoped lang="scss">
.el-tabs__item {
  position: relative;
  flex-shrink: 1;
  padding: 0 !important;
  color: var(--el-text-color-disabled);
  background-color: var(--el-bg-color-overlay);
  border: none !important;

  &:hover {
    color: var(--el-text-color-disabled) !important;
    background-color: var(--el-header-bg-color) !important;
  }

  &::before,
  &::after {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 3;
    display: block;
    width: 1px;
    background-color: var(--el-bg-color-page);
    content: '';
  }

  &::before {
    left: 0;
  }

  &::after {
    right: 0;
  }

  .tab-item-label {
    position: relative;
    z-index: 4;
    display: flex;
    flex: 1;
    align-items: center;
    height: 100%;
    padding: 0 10px;
    white-space: nowrap;

    &::before,
    &::after {
      position: absolute;
      right: 0;
      left: 0;
      display: block;
      height: 1px;
      background-color: var(--el-bg-color-page);
      content: '';
    }

    &::before {
      top: 0;
    }

    &::after {
      bottom: 0;
    }
  }

  &.is-active {
    flex-shrink: 0;
    color: var(--el-text-color-regular) !important;
    background-color: var(--el-header-bg-color) !important;

    .tab-item-label {
      &::after {
        background-color: transparent;
      }
    }
  }

  &.preview {
    display: inline-flex;
    height: 28px;
    color: var(--el-text-color-regular);
    background-color: var(--el-bg-color-page) !important;

    &::before,
    &::after {
      background-color: var(--el-bg-color-page) !important;
    }

    .tab-item-label {

      &::before,
      &::after {
        background-color: var(--el-bg-color-page) !important;
      }
    }

    &.is-active {
      color: var(--el-text-color-regular) !important;
      background-color: var(--el-bg-color-page) !important;

      &::before,
      &::after {
        background-color: var(--el-bg-color-page) !important;
      }

      .tab-item-label {

        &::before,
        &::after {
          background-color: var(--el-bg-color-page) !important;
        }
      }
    }

    .tab-item-label {
      padding: 0 10px;
    }
  }
}
</style>
